<?PHP
	/*
		Class: Template
		Representa un template de forma dinámica
	*/
	class Template {
		
		var $data;
		var $template;
		var $formsFound;
		var $content;
		
		function Template($templateURI=NULL){
			import("display.TextUtils");
			import("view.TemplateLogic");
			import("view.TemplateData");
			import("data.Options");
			$this->template = $templateURI;
			$this->formsFound = 0;
		}
		
		function getUniqueFormID(){
			$this->formsFound++;
			return "form".$this->formsFound;
		}
		
		function setContent($content){
  			$this->content = $content;
		}
		
		function setData($data){
			$this->data = new TemplateData($data);
		}
		
		function form($content,$attributes){
			$to = TemplateLogic::content($attributes["to"],$this->data);
			$name = (array_key_exists("name",$attributes)) ? TemplateLogic::content($attributes["name"],$this->data) : $this->getUniqueFormID();
			$options = array();
			$options["method"] = (array_key_exists("method",$attributes)) ? $attributes["method"] : "post" ;
			$options["action"] = linkForm($to);
			if(array_key_exists("validate",$attributes) && $attributes["validate"]) $options["onsubmit"] = "return \$validate(this);";
			//$validate(frm,debug)
			if(array_key_exists("files",$attributes) && strToLower($attributes["files"])=="true"){
				$options["enctype"] = "multipart/form-data";
			}
			$result = $this->process($content);
			$select = form_tag($name,$result,$options);
			return $select;
		}
		
		function table($content, $attributes){
			$collection = $this->data->get($attributes["collection"]);
			$elementName = (array_key_exists("as",$attributes)) ? $attributes["as"] : "item" ;
			$cols = $attributes["cols"];
			$result = "<tr>";
			$c = 0;
			$r = 0;
			foreach($collection as $item){
				$this->data->setTemporal($elementName,$item);
				$result .= simple_tag("td",$this->process($content));
				$this->data->clear("item");
				$c++;
				if($c==$cols){
					$result .="</tr><tr>";
					$c=0;
				}
				$this->data->clear($elementName);
			}	
			if($c>0){
				while($c<$cols){
					$result .= simple_tag("td","&nbsp;",array("class"=>"empty"));
					$c++;
				}
			}
			$result.="</tr>";
			$options = Options::parse($attributes["options"]);
			return simple_tag("table",$result,$options);
		}
		
		function loop($content, $attributes){
			$collection = $this->data->get($attributes["collection"]);
			$elementName = (array_key_exists("as",$attributes)) ? $attributes["as"] : "item" ;
			$result = "";
			if(is_array($collection)){
				foreach($collection as $item){
					$this->data->setTemporal($elementName,$item);
					$result .= $this->process($content);
					$this->data->clear($elementName);
				}
			}
			return $result;
		}
		
		function combo($content,$attributes){
			$defaultValues = (trim($content)=="");
			$name = $attributes["name"];
			$selected = (array_key_exists("selected",$attributes)) ? $this->process($attributes["selected"]) : NULL ;
			$result = "";
			if(array_key_exists("values",$attributes)){
				$values = explode(";",$attributes["values"]);
				foreach($values as $value){
					$data = explode(":",$value);
					$result .= option_tag($data[1],$data[0],($data[0]==$selected));
				}
			}
			
			if(array_key_exists("collection",$attributes)){
				if($defaultValues){
					$collection = $this->data->get($attributes["collection"]);
					if(is_array($collection)){
						foreach($collection as $item){
							$result .= option_tag($item->name,$item->id,($item->id==$selected));
						}
					}
				}else{
					$this->data->setTemporal("selected",$selected);
					$result .= $this->loop($content,$attributes);
					$this->data->clear("selected");
				}
			}
			$select = select_tag($name,$result);
			return $select;
		}
		
		function process($source){
			$tagsPattern = '/\<(?:(?i)mate):([^\s]*?)(?(?=[\s])(.*?))(?(?=[\/])\/>|\>(.*?)\<\/(?:(?i)mate:\1)\>)/s';
			//$contentPattern = '/\{(.*?)\}/';
			preg_match_all($tagsPattern, $source, $matches);
			$tags = array();
			$contents = array();
			for($m = 0; $m<count($matches[0]); $m++){
				$tag = $matches[0][$m];
				$tagName = strToLower($matches[1][$m]);
				if(substr($tagName,0,4)=="loop") $tagName = "loop";
				$attributesString = $matches[2][$m];
				$content = $matches[3][$m];
				
				$tags[] = $tag;
				$attributes = TemplateLogic::getAttributes($attributesString);
				if(array_key_exists("options",$attributes)===FALSE) $attributes["options"] = "";
				
				switch($tagName){
					case "comment":
						break;
					case "loop":
					case "combo":
					case "form":
					case "table":
						$contents[] = $this->$tagName($content,$attributes);
						break;
					case "if":
						$contents[] = $this->condition($content,$attributes);
						break;
					default:
						$contents[] = TemplateLogic::render($tagName,$this->data,$content,$attributes);
						break;
				}
			}
			$resultFromLogic = str_replace($tags,$contents,$source);
			return TemplateLogic::content($resultFromLogic,$this->data);
			
		}
		
		function condition($content,$attributes) {
			$condition = $this->process($attributes["condition"]);
			$conditions = array("GT","LT","NEQ","EQ","GET","LET");
			$real_conditions = array(">","<","!=","==",">=","<=");
			$condition_string = "return ".str_replace($conditions,$real_conditions,$condition).";";
			$contents = explode("<mate:else>",$content);
			if(eval($condition_string)){
				$return = $this->process($contents[0]);
			}else{
				$return = (count($contents)>1) ? $this->process($contents[1]) : "" ;
			}
			return $return;
		}
		/*
			TODO MATE TABLE
		*/
		/*
		function processTable($content,$attrs){
			$objects = $this->getObject($attrs["collection"]);
			$options = (array_key_exists("options",$attrs)) ? $this->processOptions($attrs["options"]) : array() ;
			$result = "<tr>";
			$cols = $attrs["cols"];
			$c = 0;
			$r = 0;
			for($o=0;$o<count($objects);$o++){
				$result .= simple_tag("td",$this->process($content,$objects[$o]));
				$c++;
				if($c==$cols){
					$result .="</tr><tr>";
					$c=0;
				}
			}
			if($c>0){
				while($c<$cols){
					$result .= simple_tag("td","&nbsp;");
					$c++;
				}
			}
			$result.="</tr>";
			return simple_tag("table",$result,$options);
		}
		*/
		
		function render(){
  			if(isset($data)) $this->data = $data;
			return $this->process($this->content);
		}
	}
?>
